home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 12 / Amiga Format AFCD12 (Apr 1997, Issue 96).iso / -in_the_mag- / html_tutorial / cgi_pars.ada < prev    next >
Text File  |  1997-01-21  |  6KB  |  205 lines

  1. -------------------------------------------------------------
  2. -- (C) Michael A Smith 1995-1996                           --
  3. --     Additional material about Ada 95                    --
  4. --     See http://www.brighton.ac.uk/ada95/home.html       --
  5. -------------------------------------------------------------
  6.  
  7. --(class_description.ADS) Implementation Instantiation
  8.  
  9. --
  10. -- Split the components of a CGI result string into
  11. --  individual sub strings
  12. --
  13. -- For example the string
  14. --   name=Your+name&action=%2B10%25&log=~mas/log
  15. --
  16. -- is composed of three named elements:
  17. --
  18. --     Element    String associated with element
  19. --     name       Your name
  20. --     action     +10%
  21. --     log        /usr/staff/mas/log
  22. --
  23. -- (C) M.A.Smith University of Brighton
  24. -- Permission is granted to use this code
  25. --   provided this declaration and copyright notice remains intact.
  26. -- 4 January 1996
  27. --
  28. --
  29. --
  30. -- S p e c i f i c a t i o n
  31.  
  32.  
  33. with Simple_io, Ada.Strings.Unbounded; 
  34. use  Simple_io, Ada.Strings.Unbounded;
  35. package Class_parse is
  36.   type Parse is private;
  37.   procedure set( the:in out Parse; mes:in String );
  38.   function  get_item( the:in Parse; key: in String; pos:in Integer:=1; 
  39.                      map:in Boolean :=false ) return String;
  40. private
  41.   SEP : constant Character := '&';
  42.   type Parse is record
  43.     str : Unbounded_string;            -- String to parse
  44.     len : Integer;                     -- Length
  45.   end record;
  46. end Class_parse;
  47.  
  48.  
  49.  
  50. --
  51. -- Split the components of a CGI result string into
  52. --  individual sub strings
  53. --
  54. -- For example the string
  55. --   name=Your+name&action=%2B10%25&log=~mas/log
  56. --
  57. -- is composed of three named elements:
  58. --
  59. --     Element    String associated with element
  60. --     name       Your name
  61. --     action     +10%
  62. --     log        /usr/staff/mas/log
  63. --
  64. -- (C) M.A.Smith University of Brighton
  65. -- Permission is granted to use this code
  66. --   provided this declaration and copyright notice remains intact.
  67. -- 4 January 1996
  68. --
  69. --
  70. -- I m p l e m e n t a t i o n
  71.  
  72. package body Class_parse is
  73.  
  74. function remove_escape(from:in String) return String;
  75. function hex( first, second :in Character ) return Character;
  76.  
  77. procedure set( the:in out Parse; mes:in String ) is
  78. begin
  79.   the.str := to_unbounded_string(mes);
  80.   the.len := mes'Length;
  81. end set;
  82.  
  83. function get_item( the:in Parse; key: in String; pos:in Integer:=1; 
  84.                    map:in Boolean :=false ) return String is
  85.   cur_tag   : Integer := 1;
  86.   i,j       : Integer;
  87.   start     : Integer;
  88.   parse_str : String (1 .. the.len) := to_string( the.str );
  89. begin
  90.   i := 1;
  91.   while i < the.len-key'Length loop
  92.     if parse_str(i .. i+key'Length-1) = key then
  93.       if parse_str(i+key'Length) = '=' then
  94.         if cur_tag = pos then
  95.           start := i+key'Length+1; j := start;
  96.           while j <= the.len and then parse_str(j) /= SEP loop
  97.             if j <= the.len then j := j + 1; end if;
  98.           end loop;
  99.           return remove_escape( parse_str( start .. j-1 ) );
  100.         else
  101.           cur_tag := cur_tag + 1;
  102.         end if;
  103.       end if;
  104.     end if;
  105.     i := i + 1;
  106.   end loop;
  107.   return "";
  108. end get_item;
  109.  
  110. function remove_escape(from:in String) return String is
  111.   res : String( 1 .. from'Length );
  112.   ch  : Character;
  113.   i,j : Integer;
  114. begin
  115.   i := from'First; j := 0;
  116.   while i <= from'Last loop
  117.     ch := from(i);
  118.     case ch is
  119.       when '%' =>
  120.     ch := hex(from(i+1), from(i+2) );
  121.         i:= i+2;
  122.       when '+' =>
  123.     ch := ' ';
  124.       when others =>
  125.         null;
  126.     end case;
  127.     i := i + 1;
  128.     j := j + 1; res(j) := ch;
  129.   end loop;
  130.   return res(1..j);
  131. end remove_escape;
  132.  
  133. function hex( first, second :in Character ) return Character is
  134.   type Mod256 is mod 256;
  135.   a_ch : Mod256;
  136.   function hex_value( ch:in Character ) return Mod256 is
  137.   begin
  138.     if ch in '0' .. '9' then 
  139.       return Character'Pos(ch)-Character'Pos('0');
  140.     end if;
  141.     if ch in 'A' .. 'F' then 
  142.       return Character'Pos(ch)-Character'Pos('A')+10;
  143.     end if;
  144.     return 0;
  145.   end hex_value;
  146. begin
  147.   return Character'Val(
  148.         ( hex_value(first) and 16#FF#) * 16 +
  149.         ( hex_value(second) and 16#FF#) );
  150. end hex;
  151.  
  152. end Class_parse;
  153.  
  154. package unix_if is
  155.   function get_env( str:in String ) return String;
  156. end unix_if;
  157.  
  158. with Interfaces.C, Interfaces.C.Strings;
  159. use  Interfaces.C, Interfaces.C.Strings;
  160. package body unix_if is
  161.  
  162. function get_env( str:in String ) return String is
  163.   function getenv( str:in Char_array ) return Chars_ptr;
  164.   pragma import (C, getenv, "getenv");
  165.   res : Chars_ptr;
  166. begin
  167.   res := getenv( to_c( str, append_nul=>TRUE ) );
  168.   if res = NULL_PTR then
  169.     return "";
  170.   else
  171.     return value(res);
  172.   end if;
  173. end get_env;
  174.  
  175. end unix_if;
  176.  
  177. with Simple_io, Class_parse, unix_if, Ada.Strings.Unbounded; 
  178. use  Simple_io, Class_parse, unix_if, Ada.Strings.Unbounded;
  179. procedure main is
  180.   list         : Parse;
  181.   query_string : Unbounded_string;      -- String to parse
  182.  
  183. begin
  184.   query_string := to_unbounded_string( get_env( "QUERY_STRING" ) );
  185.   if ( to_string( query_string ) = "" ) then
  186.     query_string := to_unbounded_string( 
  187.         "tag=one&"             & 
  188.         "name=mike&"           &
  189.         "action=%2B10%25&"     &
  190.         "tag=two&"             &
  191.         "log=~mas/log&"        &
  192.         "tag=three" );
  193.   end if;
  194.  
  195.   set( list, to_string(query_string) ) ;
  196.  
  197.   put("name   = "); put( get_item( list, "name" )) ; new_line;
  198.   put("action = "); put( get_item( list, "action" )) ; new_line;
  199.   put("log    = "); put( get_item( list, "log" )) ; new_line;
  200.   for i in 1 .. 4 loop
  201.     put("tag(" ); put( i, width=>1 ); put( ")  ");
  202.     put( get_item( list, "tag", i ) ); new_line;
  203.   end loop;
  204. end main;
  205.